﻿/************************************************************************

 This file is part of EscapeFromPrisonPlanet.

 EscapeFromPrisonPlanet is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 EscapeFromPrisonPlanet is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

************************************************************************/

// All code (c)2012 Scott Bevin. all rights reserved

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace LudumDare25Project
{
    internal class Menu
    {
        public delegate void MenuItemSelectedCallback(MenuEntry entry);

        public class MenuEntry
        {
            public string Text = "Invalid";

            public event MenuItemSelectedCallback Selected;

            public Vector2 Area;

            public float Alpha = 0.0f;
            public float TargetAlpha = 1.0f;

            public bool Clickable = true;

            public void Call()
            {
                if (Selected != null)
                    Selected(this);
            }
        }

        private List<MenuEntry> menuEntries = new List<MenuEntry>();
        private SpriteFont font;

        private SoundEffect hoverSfx;
        private SoundEffect clickSfx;

        public Menu(SpriteFont font, ContentManager content)
        {
            hoverSfx = content.Load<SoundEffect>("Sfx/MenuHover");
            clickSfx = content.Load<SoundEffect>("Sfx/MenuSelect");

            this.font = font;
        }

        public void AddEntry(string text, MenuItemSelectedCallback SelFunc)
        {
            MenuEntry newEntry = new MenuEntry();
            newEntry.Text = text;
            newEntry.Selected += SelFunc;
            newEntry.Area = font.MeasureString(text);
            menuEntries.Add(newEntry);
        }

        public void AddNonClickEntry(string text, MenuItemSelectedCallback SelFunc)
        {
            MenuEntry newEntry = new MenuEntry();
            newEntry.Text = text;
            newEntry.Selected += SelFunc;
            newEntry.Area = font.MeasureString(text);
            newEntry.Clickable = false;

            menuEntries.Add(newEntry);
        }

        private MenuEntry lastHoverEntry = null;

        public void Update(float dt, InputManager input, GraphicsDevice gd)
        {
            MenuEntry hoverEntry = GetMenuEntry(gd, input.CurrentMousePos);

            if (hoverEntry != null)
            {
                if (hoverEntry != lastHoverEntry)
                {
                    hoverSfx.Play();
                }

                lastHoverEntry = hoverEntry;

                for (int i = 0; i < menuEntries.Count; ++i)
                {
                    menuEntries[i].TargetAlpha = 0.25f;
                }

                hoverEntry.TargetAlpha = 1.0f;
            }
            else
            {
                for (int i = 0; i < menuEntries.Count; ++i)
                {
                    menuEntries[i].TargetAlpha = 1.0f;
                }
            }

            for (int i = 0; i < menuEntries.Count; ++i)
            {
                menuEntries[i].Alpha = MathHelper.Lerp(menuEntries[i].Alpha, menuEntries[i].TargetAlpha, dt * 3.0f);
            }

            if (hoverEntry != null && input.MouseButtonStates[(int)InputManager.MouseButtons.LeftButton].Pressed)
            {
                hoverEntry.Call();
                clickSfx.Play();
            }
        }

        private MenuEntry GetMenuEntry(GraphicsDevice gd, Vector2 screenPos)
        {
            Vector2 basePosition = new Vector2(((float)gd.PresentationParameters.BackBufferWidth) * 0.5f,
                ((float)gd.PresentationParameters.BackBufferHeight) * 0.5f);

            foreach (MenuEntry me in menuEntries)
            {
                if (me.Clickable)
                {
                    if (screenPos.X <= basePosition.X + (me.Area.X * 0.5f) &&
                        screenPos.X >= basePosition.X - (me.Area.X * 0.5f) &&
                        screenPos.Y <= basePosition.Y + (me.Area.Y * 0.5f) &&
                        screenPos.Y >= basePosition.Y - (me.Area.Y * 0.5f))
                    {
                        return me;
                    }
                }

                basePosition.Y += (me.Area.Y * 0.5f);
            }

            return null;
        }

        public void OnClick(GraphicsDevice gd, Vector2 screenPos)
        {
            //   MenuEntry me = GetMenuEntry(gd, screenPos);

            //     if (me != null && me.Selected != null)
            //          me.Selected(me);
        }

        public void Render(GraphicsDevice gd, SpriteBatch sprites)
        {
            Vector2 basePosition = new Vector2(((float)gd.PresentationParameters.BackBufferWidth) * 0.5f,
                ((float)gd.PresentationParameters.BackBufferHeight) * 0.5f);

            sprites.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);

            foreach (MenuEntry me in menuEntries)
            {
                sprites.DrawString(
                    font,
                    me.Text,
                    basePosition,
                    Color.Black * me.Alpha,
                    0.0f,
                    me.Area * 0.5f,
                    1.0f,
                    SpriteEffects.None,
                    0.0f);

                basePosition.Y += (me.Area.Y * 0.5f);
            }

            sprites.End();
        }
    }
}